package org.ala.tiktools.sharddb.mybatis.pager.after_pager;

import org.ala.tiktools.mybatis.interfaces.AbstractOrderBy;
import org.ala.tiktools.mybatis.pager.Pager;
import org.ala.tiktools.sharddb.mybatis.executor.ShardExecutor;
import org.ala.tiktools.sharddb.mybatis.executor.ShardNoTxExecutor;
import org.ala.tiktools.sharddb.mybatis.pager.parameter.ShardPagerParameter;
import org.ala.tiktools.sharddb.mybatis.router.ShardInfo;
import org.ala.tiktools.tools.kv.KV;
import org.ala.tiktools.tools.kv.Maps;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * after分页方式
 * <p>  要求分页字段一定得是唯一索引
 *
 * @author ala
 * @date 2025-03-08 17:51
 */
public class ShardAfterPagerHandler {


    /**
     *  执行after分页
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public Map<ShardInfo, ShardExecutor.Result> doAfterPager(ShardPagerParameter parameter) {
        //  查总数量
        Map<ShardInfo, ShardExecutor. Result> r = ShardNoTxExecutor.doInvoke(parameter.getAnno(), parameter.getThreadPool(), parameter.getCountMethod().getArgs(), parameter.getCountMethod().getProxy(), parameter.getCountMethod().getMethod());
        int total = r.values().stream().mapToInt(e -> ((Integer)e.getRes()).intValue()).sum();

        Pager pager = parameter.getPager();
        AbstractOrderBy orderBy = parameter.getOrderBy();
        List datas = doQuery(parameter);

        if (!datas.isEmpty()) {
            orderBy.setCurrentItemVal(datas.get(datas.size() - 1));
        }
        return Maps.build(KV.build(ShardInfo.EMPTY, ShardExecutor.Result.success(ShardInfo.EMPTY, Pager.build(pager.getNo(), pager.getSize()).datas(datas).total(total))));
    }


    /**
     *  每个分表取第一页数据，结果汇总
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	protected List doQuery(ShardPagerParameter parameter) {
        Pager pager = parameter.getPager();
        pager.setNo(1);

        Map<ShardInfo, ShardExecutor. Result> r = ShardNoTxExecutor.doInvoke(parameter.getAnno(), parameter.getThreadPool(), parameter.getDataMethod().getArgs(), parameter.getDataMethod().getProxy(), parameter.getDataMethod().getMethod());
        List list = new ArrayList();
        r.values().forEach(e -> {
            Pager p = (Pager) e.getRes();
            list.addAll(p.getDatas());
        });
        list.sort(parameter.getOrderBy());
        return list.size() < pager.getSize() ? list : list.subList(0, pager.getSize());
    }
}
